package com.sdy.hospitalguard.web.controller;

import com.sdy.common.model.Response;
import com.sdy.common.utils.StringUtil;
import com.sdy.hospitalguard.biz.constants.Constants;
import com.sdy.hospitalguard.biz.constants.RedisConstants;
import com.sdy.hospitalguard.biz.model.Manager;
import com.sdy.hospitalguard.biz.service.ManagerService;
import com.sdy.hospitalguard.biz.utils.PassWordUtil;
import com.sdy.mvc.controller.BaseController;
import com.sdy.redis.service.RedisService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author: 王越洋
 * @version: v1.0
 * @description: com.sdy.hospitalguard.web.controller
 * @date:2020/5/26
 */

@RestController
@RequestMapping("/login")
@Api(tags = "登录接口")
public class LoginController extends BaseController {
    @Autowired
    private RedisService redisService;
    @Autowired
    private ManagerService managerService;

    @PostMapping("/webTestLogin")
    @ApiOperation(value = "PC登录验证")
    public Response webTestLogin(HttpServletRequest request, String phone, String password) {
//        if (phone == null || !phone.matches(Constants.REGEX_PHONE)) {
//            return Response.error("手机号格式错误。");
//        }
//        if (checkErrorTimesOverflow(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone)) {
//            return Response.error("密码错误次数过多，请" + Constants.LOGIN_FAILED_LOCK_MINUTE + "分钟后再试。");
//        }
//        if (StringUtil.isBlank(password)) {
//            return Response.error("密码不能为空。");
//        }
        Manager manager = managerService.lambdaQuery()
                .eq(Manager::getPhone, phone)
                .one();
//        if (manager == null) {
//            return Response.error("用户不存在。");
//        }
//        if (!manager.getState().equals(1)) {
//            return Response.error("用户不可用。");
//        }
//        if (!password.equals(manager.getPassword())) {
//            addErrorTimes(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone);
//            if (checkErrorTimesOverflow(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone)) {
//                return Response.error("密码错误次数过多，请" + Constants.LOGIN_FAILED_LOCK_MINUTE + "分钟后再试。");
//            }
//            return Response.error("密码不正确。");
//        }
        redisService.del(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone);
        request.getSession().setAttribute(Constants.SESSION_WEB_USER_ID, manager.getId());
        return Response.success("测试登陆成功");
    }

    /**
     * PC登录验证
     *
     * @param map 参数map
     */
    @PostMapping("/webLoginWithPassword")
    @ApiOperation(value = "PC登录验证")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(value = "手机号", name = "phone", required = true),
            @ApiImplicitParam(value = "密码", name = "password", required = true)
    })
    public Response webLoginWithPwd(HttpServletRequest request, @RequestBody @ApiParam(value = "map", name = "放入phone + password") Map<String, String> map) {
        String phone = map.get("phone");
        String password = map.get("password");
        if (phone == null || !phone.matches(Constants.REGEX_PHONE)) {
            return Response.error("手机号格式错误。");
        }
        if (checkErrorTimesOverflow(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone)) {
            return Response.error("密码错误次数过多，请" + Constants.LOGIN_FAILED_LOCK_MINUTE + "分钟后再试。");
        }
        if (StringUtil.isBlank(password)) {
            return Response.error("密码不能为空。");
        }
        Manager manager = managerService.getByPhone(phone);
        if (manager == null) {
            return Response.error("用户不存在。");
        }
        if (!manager.getState().equals(0)) {
            return Response.error("用户不可用。");
        }
        if (!PassWordUtil.loginVerify(password, manager.getPassword())) {
            addErrorTimes(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone);
            if (checkErrorTimesOverflow(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone)) {
                return Response.error("密码错误次数过多，请" + Constants.LOGIN_FAILED_LOCK_MINUTE + "分钟后再试。");
            }
            return Response.error("密码不正确。");
        }
        redisService.del(RedisConstants.LOGIN_WEB_FAILED_TIMES + phone);
        request.getSession().setAttribute(Constants.SESSION_WEB_USER_ID, manager.getId());
        return Response.success();
    }

    @GetMapping("/logout")
    @ApiOperation(value = "登出")
    public Response logout(HttpServletRequest request) {
        request.getSession().removeAttribute(Constants.SESSION_WEB_USER_ID);
        return Response.success();
    }

    private void addErrorTimes(String key) {
        redisService.incr(key);
        redisService.expire(key, Constants.LOGIN_FAILED_LOCK_MINUTE * 60);
    }

    private boolean checkErrorTimesOverflow(String key) {
        Integer t = redisService.get(key, Integer.class);
        boolean overflow = t != null && t >= Constants.LOGIN_FAILED_MAX_TIMES;
        if (overflow) {
            if (redisService.ttl(key).equals(-1L)) {
                redisService.expire(key, Constants.LOGIN_FAILED_LOCK_MINUTE * 60);
            }
        }
        return overflow;
    }
}
